package com.ctshk.rpc.order.train.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ctshk.common.dto.Result;
import com.ctshk.common.enums.*;
import com.ctshk.common.exception.BusinessException;
import com.ctshk.common.model.TokenUser;
import com.ctshk.rpc.airexpress.dto.AirportExpressInfoDTO;
import com.ctshk.rpc.airexpress.service.IAirportExpressService;
import com.ctshk.rpc.finance.req.bill.BillAddRefundReq;
import com.ctshk.rpc.finance.req.bill.BillOperateRefundReq;
import com.ctshk.rpc.finance.service.IFinanceBillService;
import com.ctshk.rpc.order.train.entity.TrainOrder;
import com.ctshk.rpc.order.train.entity.TrainOrderRefund;
import com.ctshk.rpc.order.train.mapper.TrainOrderMapper;
import com.ctshk.rpc.order.train.mapper.TrainOrderRefundMapper;
import com.ctshk.rpc.order.train.req.TrainOrderRefundApprovalRecordReq;
import com.ctshk.rpc.order.train.req.TrainOrderRefundApprovalReq;
import com.ctshk.rpc.order.train.req.TrainOrderRefundUpdateReq;
import com.ctshk.rpc.order.train.service.ITrainOrderRefundService;
import com.ctshk.rpc.system.dto.UserDTO;
import com.ctshk.rpc.system.service.ISysUserService;
import com.ctshk.rpc.train.dto.TrainProductDTO;
import com.ctshk.rpc.train.dto.TrainProductReservationSettingsDTO;
import com.ctshk.rpc.train.service.ITrainProductService;
import com.ctshk.rpc.workflow.dto.ApprovalCheckDTO;
import com.ctshk.rpc.workflow.service.ISysApprovalService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;


/**
 * <p>
 * 火车退款记录 服务实现类
 * </p>
 *
 * @author 彭柳霖
 * @since 2021-03-17
 */
@DubboService
@Slf4j
public class TrainOrderRefundServiceImpl extends ServiceImpl<TrainOrderRefundMapper, TrainOrderRefund> implements ITrainOrderRefundService {

    @Autowired
    private TrainOrderRefundMapper trainOrderRefundMapper;

    @DubboReference
    private IFinanceBillService iFinanceBillService;

    @Autowired
    private TrainOrderMapper trainOrderMapper;

    @DubboReference
    ISysUserService sysUserService;

    @DubboReference
    IFinanceBillService financeBillService;

    @DubboReference
    ISysApprovalService sysApprovalService;

    @DubboReference
    ITrainProductService trainProductService;

    /**
     * 操作退款
     *
     * @param refundId 退款明细id
     *         userId 用户id
     * @return 返回值
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result delete(Long refundId, Long userId) {
        TrainOrderRefund trainOrderRefund = trainOrderRefundMapper.selectById(refundId);
        if(Objects.isNull(trainOrderRefund)){
            return Result.failed(SystemError.TRAIN_PRODUCT_14025);
        }

        if (trainOrderRefund.getStatus() != OrderRefundStatus.AUDIT_FAILED.getCode()) {
            // 审批失败状态的退款记录才可以删除
            throw new BusinessException(SystemError.TRAIN_PRODUCT_14028);
        }

        trainOrderRefund.setIsDeleted(IsDeletedCode.NO.getCode());
        trainOrderRefund.setGmtModified(LocalDateTime.now());
        trainOrderRefund.setModifiedId(userId);
        trainOrderRefundMapper.updateById(trainOrderRefund);
        return Result.success();
    }

    @Override
    public Result refund(TrainOrderRefundUpdateReq trainOrderRefundUpdateReq, TokenUser tokenUser) {
        TrainOrderRefund trainOrderRefund = baseMapper.selectById(trainOrderRefundUpdateReq.getId());
        if(trainOrderRefund != null){
            trainOrderRefund.setModifiedId(tokenUser.getId());
            trainOrderRefund.setGmtModified(LocalDateTime.now());
            trainOrderRefund.setStatus(3);
            baseMapper.updateById(trainOrderRefund);
        }

        //財務-操作退款
        if(StringUtils.isNotBlank(trainOrderRefundUpdateReq.getBillNumber())){
            BillOperateRefundReq billOperateRefundReq = new BillOperateRefundReq();
            billOperateRefundReq.setBillNumber(trainOrderRefundUpdateReq.getBillNumber());
            billOperateRefundReq.setBusinessType(SystemBusinessType.LOCAL_FUN.getCode());
            billOperateRefundReq.setUserId(tokenUser.getId());

            iFinanceBillService.operateRefund(billOperateRefundReq);
        }
        return Result.success(trainOrderRefund.getId());
    }

    @Override
    public Result confirmRefund(String refundNumber, Long userId) {
        TrainOrderRefund trainOrderRefund = baseMapper.selectOne(Wrappers.<TrainOrderRefund>lambdaQuery()
                .eq(TrainOrderRefund::getRefundNumber, refundNumber));
        if (trainOrderRefund == null) {
            //收款记录不存在
            return Result.failed(SystemError.AIREXPRESS_ORDER_60028);
        }
        trainOrderRefund.setStatus(ApprovalStatus.REFUND_SUCCESS.getCode());
        trainOrderRefund.setModifiedId(userId);
        trainOrderRefund.setGmtModified(LocalDateTime.now());
        baseMapper.updateById(trainOrderRefund);
        return Result.success();
    }

    @Override
    public Result approval(TrainOrderRefundApprovalReq req) {
        /*if (req.getApprovalId() == null) {
            return Result.failed(SystemError.SYS_402);
        }
        if (!ApprovalStatus.isCheckStatus(req.getApprovalStatus())) {
            return Result.failed(SystemError.SYS_402);
        }
        QueryWrapper<TrainOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.lambda().eq(TrainOrder::getId, req.getBusinessId());
        orderQueryWrapper.lambda().eq(TrainOrder::getIsDeleted, IsDeletedCode.NO);
        TrainOrder trainOrder = trainOrderMapper.selectOne(orderQueryWrapper);
        if (trainOrder == null) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60002);
        }
        if (!ApprovalStatus.REVIEWING.getCode().equals(trainOrder.getCancelStatus())) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60027);
        }
        QueryWrapper<TrainOrderRefund> orderRefundQueryWrapper = new QueryWrapper<>();
        orderRefundQueryWrapper.lambda().eq(TrainOrderRefund::getOrderId, req.getBusinessId());
        orderRefundQueryWrapper.lambda().eq(TrainOrderRefund::getIsDeleted, IsDeletedCode.NO);
        List<TrainOrderRefund> trainOrderRefundList = trainOrderRefundMapper.selectList(orderRefundQueryWrapper);
        if (CollectionUtils.isEmpty(trainOrderRefundList)) {
            return Result.failed(SystemError.AIREXPRESS_ORDER_60028);
        }
        LocalDateTime nowLocalDateTime = LocalDateTime.now();
        log.info("【火车票订单-退款】approval status:{}", req.getApprovalStatus());
        if (ApprovalStatus.REVIEW_YES.getCode() == req.getApprovalStatus()) {
            if (CollectionUtils.isEmpty(req.getOrderRefundApprovalRecordReqList())) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60036);
            }
            // 审批通过
            trainOrder.setCancelStatus(ApprovalStatus.REVIEW_YES.getCode());
            // 校验审批金额
            BigDecimal totalAmount = BigDecimal.ZERO;
            for (TrainOrderRefund refund : trainOrderRefundList) {
                refund.setStatus(ApprovalStatus.REVIEW_YES.getCode());
                for (TrainOrderRefundApprovalRecordReq orderRefundApprovalRecordReq : req.getOrderRefundApprovalRecordReqList()) {
                    if (Objects.equals(orderRefundApprovalRecordReq.getId(), refund.getId())) {
                        BigDecimal approvalAmount = orderRefundApprovalRecordReq.getApprovalAmount();
                        totalAmount = totalAmount.add(approvalAmount.multiply(refund.getExchangeRate()));
                        refund.setApprovalAmount(orderRefundApprovalRecordReq.getApprovalAmount());
                        break;
                    }
                }
            }
            TrainProductDTO trainProductDTO = trainProductService.queryDetail(trainOrder.getTrainId());
            // 获取预订设置
            TrainProductReservationSettingsDTO trainProductReservationSettingsDTO = trainProductDTO.getTrainProductReservationSettingsDTO();
            if(trainProductReservationSettingsDTO != null)
            //BigDecimal cancellationCharge = trainProductService.getCancellationChargeById(airportExpressOrder.getAirportExpressId(), airportExpressOrder.getReceivableAmount());
            //BigDecimal refundAmount = trainOrder.getReceivableAmount().subtract(cancellationCharge);
            *//*if (totalAmount.compareTo(refundAmount) > 0) {
                throw new BusinessException(SystemError.AIREXPRESS_ORDER_60035);
            }*//*
            *//**
             * 新增财务退款记录
             *//*
            UserDTO userSaleDTO = sysUserService.queryCacheUser(trainOrder.getSalesmanId());
            List<BillAddRefundReq> billAddRefundReqs = new ArrayList<>();
            for (TrainOrderRefund orderRefund : trainOrderRefundList) {
                BillAddRefundReq billAddRefundReq = new BillAddRefundReq();
                billAddRefundReqs.add(billAddRefundReq);
                billAddRefundReq.setBillNumber(orderRefund.getRefundNumber());
                billAddRefundReq.setBusinessType(SystemBusinessType.TRAIN_TICKET.getCode());
                billAddRefundReq.setCollectionAmount(orderRefund.getRefundAmount());
                billAddRefundReq.setCurrencyId(orderRefund.getCurrencyId());
                billAddRefundReq.setCurrencyName(orderRefund.getCurrency());
                billAddRefundReq.setExchangeRate(BigDecimal.ONE.doubleValue());
                billAddRefundReq.setRefundTime(orderRefund.getGmtCreate());
                billAddRefundReq.setSaleOrderNumber(trainOrder.getOrderNumber());
                billAddRefundReq.setSaleOrderId(trainOrder.getId());
                billAddRefundReq.setProductId(Arrays.asList(trainOrder.getTrainId()));
                billAddRefundReq.setProductName(trainProductDTO.getTypeName());
                billAddRefundReq.setProductNumber(trainProductDTO.getProductCode());
                billAddRefundReq.setResourceInfo(Arrays.asList(trainProductDTO.getTypeName()));
                billAddRefundReq.setSaleUserId(userSaleDTO.getId());
                billAddRefundReq.setSaleUserName(userSaleDTO.getFullName());
                billAddRefundReq.setSaleDeptId(userSaleDTO.getDeptId());
                billAddRefundReq.setUserId(req.getUserId());
            }
            log.info("【火车订单退款】新增财务退款记录，req:{}", JSON.toJSONString(billAddRefundReqs));
            financeBillService.addRefund(billAddRefundReqs);
        } else if (ApprovalStatus.REVIEW_NO.getCode() == req.getApprovalStatus()) {
            //审批不通过
            trainOrder.setCancelStatus(ApprovalStatus.REVIEW_NO.getCode());
            for (TrainOrderRefund trainOrderRefund : trainOrderRefundList) {
                trainOrderRefund.setStatus(ApprovalStatus.REVIEW_NO.getCode());
            }
        } else {
            //撤回
            trainOrder.setCancelStatus(null);
            for (TrainOrderRefund trainOrderRefund : trainOrderRefundList) {
                trainOrderRefund.setStatus(null);
                trainOrderRefund.setIsDeleted(IsDeletedCode.YES.getCode());
            }
        }
        *//**
         * 审批
         *//*
        Result<ApprovalCheckDTO> result = sysApprovalService.check(req.getApprovalId(), req.getUserId(),
                req.getApprovalStatus(), req.getComments());
        if (!result.isSuccess()) {
            SystemError systemError = SystemError.getDefined(result.getCode());
            return Result.failed(systemError);
        }
        if (result.getData() == null || !result.getData().getIsFinish()) {
            return Result.success();
        }
        for (TrainOrderRefund trainOrderRefund : trainOrderRefundList) {
            trainOrderRefund.setModifiedId(req.getUserId());
            trainOrderRefund.setGmtModified(nowLocalDateTime);
            trainOrderRefundMapper.updateById(trainOrderRefund);
        }
        trainOrder.setModifiedId(req.getUserId());
        trainOrder.setGmtModified(nowLocalDateTime);
        trainOrderMapper.updateById(trainOrder);*/
        return Result.success();
    }

}
